#include <iostream>
#include <cassert>
#include <unistd.h>

#include "Epoller.h"

// 创建epoll实例，初始化事件数组
Epoller::Epoller(unsigned max_events) : epoll_fd(epoll_create1(0)), epoll_events(max_events) {
    if (epoll_fd == -1) {
        close(epoll_fd);
        std::cerr << "ERROR: Failed to create epoll.\n";  // TODO: 日志输出错误
        exit(EXIT_FAILURE);
    }

    this->epoll_events.reserve(max_events);  // vector预先预留MAX_EVENTS
}

Epoller::~Epoller() {
    close(this->epoll_fd);
//    delete epoll_events;
}

bool Epoller::add_event(int fd, uint32_t events) const {
    if (fd < 0)
        return false;
    struct epoll_event _event{};
    // TODO: 可以复用吗？
    _event.data.fd = fd;
    _event.events = events;

    return 0 == epoll_ctl(this->epoll_fd, EPOLL_CTL_ADD, _event.data.fd, &_event);
}

bool Epoller::modify_event(int fd, uint32_t events) const {
    if (fd < 0)
        return false;
    struct epoll_event _event{};  // TODO: 可以复用吗？
    _event.data.fd = fd;
    _event.events = events;

    return 0 == epoll_ctl(this->epoll_fd, EPOLL_CTL_MOD, _event.data.fd, &_event);
}

bool Epoller::delete_event(int fd) const {
    if (fd < 0)
        return false;

    return 0 == epoll_ctl(this->epoll_fd, EPOLL_CTL_DEL, fd, nullptr);
}

int Epoller::epoller_wait(int timeout) {
    return epoll_wait(this->epoll_fd, &epoll_events[0], static_cast<int>(epoll_events.size()), timeout);
}

int Epoller::get_event_fd(size_t index) const {
    assert(index < epoll_events.size() && index >= 0);
    return epoll_events[index].data.fd;
}

uint32_t Epoller::get_events(size_t index) const {
    assert(index < epoll_events.size() && index >= 0);
    return epoll_events[index].events;
}